home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / GX Libraries / QDLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-04  |  13.4 KB  |  409 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        QDLibrary.c
  4.  
  5.     Contains:    graphics libraries - quickdraw conversion library
  6.     
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  8.     
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <4>      5/4/95    JD        cleaning out fixed and fract
  14.          <3>      4/7/95    jtd        taking out all references to 'GestaltEqu.h'
  15.          <2>      1/9/95    JD        changed 'boolean' to 'Boolean'
  16.          <1>      1/9/95    JD        First checked in.
  17. */
  18.  
  19. #include <Errors.h>
  20. #include <Quickdraw.h>
  21. #include <Memory.h>
  22. #include <Resources.h>
  23. #include <Gestalt.h>
  24. #include "GraphicsLibraries.h"
  25. #include "OffscreenLibrary.h"
  26. #include "QDLibrary.h"
  27.  
  28.  
  29. gxRectangle *ShortRectToFixed(const Rect *shortRect, gxRectangle *fixedRect)
  30. {
  31.     register Fixed *coord;
  32.     
  33.     NilParamReturnNil(shortRect);
  34.     NilParamReturnNil(fixedRect);
  35.     coord = (Fixed *) fixedRect;
  36.     *coord++ = IntToFixed(shortRect->left);
  37.     *coord++ = IntToFixed(shortRect->top);
  38.     *coord++ = IntToFixed(shortRect->right);
  39.     *coord    = IntToFixed(shortRect->bottom);
  40.     return fixedRect;
  41. }
  42.  
  43.  
  44. Rect *FixedRectToShort(const gxRectangle *fixedRect, Rect *shortRect)
  45. {
  46.     register short *coord;
  47.     
  48.     NilParamReturnNil(shortRect);
  49.     NilParamReturnNil(fixedRect);
  50.     coord = (short *) shortRect;
  51.     *coord++ = FixedRound(fixedRect->top);
  52.     *coord++ = FixedRound(fixedRect->left);
  53.     *coord++ = FixedRound(fixedRect->bottom);
  54.     *coord     = FixedRound(fixedRect->right);
  55.     return shortRect;
  56. }
  57.  
  58. gxPoint *ShortPointToFixed(const Point *shortPoint, gxPoint *fixedPoint)
  59. {
  60.     NilParamReturnNil(shortPoint);
  61.     NilParamReturnNil(fixedPoint);
  62.     fixedPoint->x = IntToFixed(shortPoint->h);
  63.     fixedPoint->y = IntToFixed(shortPoint->v);
  64.     return fixedPoint;
  65. }
  66.  
  67.  
  68. Point *FixedPointToShort(const gxPoint *fixedPoint, Point *shortPoint)
  69. {   
  70.     NilParamReturnNil(shortPoint);
  71.     NilParamReturnNil(fixedPoint);
  72.     shortPoint->h = FixedRound(fixedPoint->x);
  73.     shortPoint->v = FixedRound(fixedPoint->y);
  74.     return shortPoint;
  75. }
  76.  
  77. static gxColorSet CTabPtrToColorSet(const CTabPtr qdColors)
  78. {
  79.     gxColorSet gnuSet;
  80.  
  81.     NilParamReturnNil(qdColors);
  82.     {   gxSetColor *tempColors, *colorPtr;
  83.         unsigned short *qdSpec;
  84.         short count, size;
  85.  
  86.         size = qdColors->ctSize + 1;
  87.         tempColors = (gxSetColor *) NewPtr(size * sizeof(gxSetColor));
  88.         NilParamReturnNil(tempColors);
  89.         count = size;
  90.         colorPtr = tempColors;
  91.         qdSpec = (unsigned short *) &qdColors->ctTable;
  92.         while (--count >= 0)
  93.         {
  94.             ++qdSpec;
  95.             colorPtr->rgb.red = *qdSpec++;
  96.             colorPtr->rgb.green = *qdSpec++;
  97.             colorPtr->rgb.blue = *qdSpec++;
  98.             ++colorPtr;
  99.         }
  100.         gnuSet = GXNewColorSet(gxRGBSpace, size, tempColors);
  101.         DisposePtr((Ptr) tempColors);
  102.     }
  103.     return gnuSet;
  104. }
  105.  
  106.  
  107. gxColorSet CTableToColorSet(const CTabHandle qdColors)
  108. {   char flags;
  109.     gxColorSet gnuSet;
  110.  
  111.     NilParamReturnNil(qdColors);
  112.     flags = HGetState((Handle)qdColors);
  113.     HLock((Handle)qdColors);
  114.     gnuSet = CTabPtrToColorSet(*qdColors);
  115.     HSetState((Handle)qdColors,flags);
  116.     return gnuSet;
  117. }
  118.  
  119.  
  120. CTabHandle ColorSetToCTable(const gxColorSet set)
  121. {
  122.     long i,n,numbertocopy;
  123.     CTabHandle mycolortable;
  124.     gxSetColor * mycolorlist;
  125.     gxColorSpace setSpace;
  126.     
  127.     NilColorSetReturnNil(set);
  128.     n = GXGetColorSet(set, nil, nil);
  129.     if (n < 4) numbertocopy = 2;
  130.     else if (n < 16) numbertocopy = 4;
  131.     else if (n < 256) numbertocopy = 16;
  132.     else numbertocopy = 256;
  133.     mycolorlist = (gxSetColor *)NewPtr(sizeof(gxSetColor)*numbertocopy);
  134.     NilParamReturnNil(mycolorlist);
  135.     mycolortable = (CTabHandle)NewHandle(sizeof(ColorTable)+numbertocopy*sizeof(ColorSpec));
  136.     NilParamReturnNil(mycolortable);
  137.     GXGetColorSet(set, &setSpace, mycolorlist );
  138.     (*mycolortable)->ctSeed = 0;
  139.     (*mycolortable)->ctFlags = 0;
  140.     (*mycolortable)->ctSize = numbertocopy-1;
  141.     for (i = 0; i < numbertocopy; i++) 
  142.     {   gxColor tempcolor;
  143.     
  144.         tempcolor.element.rgba = mycolorlist[i].rgba;
  145.         tempcolor.space = setSpace;
  146.         tempcolor.profile = nil;
  147.         if (setSpace != gxRGBSpace) GXConvertColor(&tempcolor,gxRGBSpace, nil, nil);
  148.         (*mycolortable)->ctTable[i].value = 0;
  149.         (*mycolortable)->ctTable[i].rgb.red = tempcolor.element.rgb.red;
  150.         (*mycolortable)->ctTable[i].rgb.green = tempcolor.element.rgb.green;
  151.         (*mycolortable)->ctTable[i].rgb.blue = tempcolor.element.rgb.blue;
  152.     }
  153.     return mycolortable;
  154. }
  155.  
  156.  
  157. /*** WARNING - this proc. should only be used with a rowBytes that is a multiple of four */
  158. /*** We should rev this to no longer have this restriction (by copying the gxBitmap, for example) */
  159. gxBitmap *ConvertFromQDBitmap(const BitMap *qdBits, gxBitmap *newBits)
  160. {
  161.     NilParamReturnNil(qdBits);
  162.     NilParamReturnNil(newBits);
  163.     newBits->image = (char *) qdBits->baseAddr;
  164.     newBits->rowBytes = qdBits->rowBytes;
  165.     newBits->width = qdBits->bounds.right - qdBits->bounds.left;
  166.     newBits->height = qdBits->bounds.bottom - qdBits->bounds.top;
  167.     newBits->pixelSize = 1;
  168.     newBits->space = gxIndexedSpace;
  169.     newBits->set = nil;
  170.     newBits->profile = nil;
  171.     return newBits;
  172. }
  173.  
  174. BitMap *ConvertToQDBitmap(const gxBitmap *newBits, BitMap *qdBits)
  175. {
  176.     NilParamReturnNil(qdBits);
  177.     NilParamReturnNil(newBits);
  178.     qdBits->baseAddr = (Ptr) newBits->image;
  179.     qdBits->rowBytes = newBits->rowBytes;
  180.     SetRect(&qdBits->bounds, 0, 0, newBits->width, newBits->height);
  181.     return qdBits;
  182. }
  183.  
  184. gxShape BitMapToShape(const BitMap *srcBits)
  185. {
  186.     gxBitmap newBits;
  187.     gxShape bitmapShape;
  188.  
  189.     NilParamReturnNil(srcBits);
  190.     bitmapShape = GXNewBitmap(ConvertFromQDBitmap(srcBits, &newBits), nil);
  191.     return bitmapShape;
  192. }
  193.  
  194. gxShape PixMapToShape(const PixMapHandle pmHandle)
  195. {
  196.     gxShape bitsShape;        /* the result gxShape */
  197.     PixMap pixmaprecord;    /* the header is read into here if we're using partial resources */
  198.     PixMap *pixmap;     /* points either into the resource or to the above record */
  199.     gxBitmap srcBits;
  200.     gxBitmap dstBits;
  201.     register short srcRowBytes;
  202.     char savedHandleFlags;      /* so we can restore the handle state after we lock it */
  203.     Boolean partialReads = false;   /* are we using partial resources to read a bit at a time? */
  204.     
  205.     NilParamReturnNil(pmHandle);
  206.     if (*pmHandle == nil) {
  207. #ifndef cpuNewton
  208.         long systemVersion; /* filled out by Gestalt */
  209.         OSErr err;
  210.         
  211.         /* The resource isn't loaded.  Try to read it in all at once, since that's quite a bit faster,
  212.           * but if that isn't possible because there isn't enough memory, use the partial resource
  213.           * manager to read it in a bit at a time.
  214.           */
  215.         LoadResource((Handle) pmHandle);
  216.         err = ResError();
  217.         if (err == memFullErr && Gestalt(gestaltSystemVersion, &systemVersion) == noErr && systemVersion >= 1792) {
  218.             partialReads = true;
  219.             ReadPartialResource((Handle) pmHandle, 0, (Ptr) (pixmap = &pixmaprecord), sizeof(pixmaprecord));
  220.             if ((err = ResError()) != 0) goto returnResError;
  221.         } else if (err) {
  222.         returnResError:
  223.                 GXPostGraphicsError(err);
  224.                 return nil;
  225.         } else {
  226.             (*pmHandle)->pmTable = nil;
  227.             (*pmHandle)->baseAddr = nil;
  228.         }
  229. #else
  230.     DebugStr("PixMapToShape: no support for zero Handles");
  231. #endif
  232.     }
  233.  
  234. #ifdef cpuNewton
  235.     (*pmHandle)->pmTable = nil;
  236.     (*pmHandle)->baseAddr = nil;
  237. #endif
  238.     
  239.     savedHandleFlags = HGetState((Handle) pmHandle);
  240.     HLock((Handle) pmHandle);
  241.     if (partialReads == false)
  242.         pixmap = *pmHandle;
  243.     dstBits.space = gxIndexedSpace;
  244.     dstBits.set = nil;
  245.     dstBits.profile = nil;
  246.     dstBits.pixelSize = pixmap->pixelSize;
  247.     dstBits.width = pixmap->bounds.right - pixmap->bounds.left;
  248.     dstBits.height = pixmap->bounds.bottom - pixmap->bounds.top;
  249.     srcRowBytes = pixmap->rowBytes & 0x3FFF;
  250.     dstBits.rowBytes = srcRowBytes;
  251.     if (dstBits.pixelSize <= 8) {
  252.         CTabHandle ctHandle;
  253.         
  254.         if (partialReads) {
  255.             long resourceOffset = sizeof(PixMap) + srcRowBytes * dstBits.height;
  256.             ColorTable cTable;
  257.             CTabPtr ctPtr;
  258.             long size;
  259.             
  260.             ReadPartialResource((Handle) pmHandle, resourceOffset, (Ptr) &cTable, sizeof(cTable));
  261.             size = sizeof(ColorTable) - sizeof(CSpecArray) + cTable.ctSize * sizeof(CSpecArray);
  262.             ctPtr = (CTabPtr) NewPtr(size);
  263.             IfDebug(ctPtr == nil, "\pcouldn't allocate CTabPtr");
  264.             ReadPartialResource((Handle) pmHandle, resourceOffset, (Ptr) ctPtr, size);
  265.             dstBits.set = CTabPtrToColorSet(ctPtr);
  266.             DisposePtr((Ptr) ctPtr);
  267.         } else if ((ctHandle = pixmap->pmTable) != nil)
  268.             dstBits.set = CTableToColorSet(ctHandle);
  269.         else
  270.             dstBits.set = CTabPtrToColorSet((CTabPtr) ((char *) pixmap + sizeof(PixMap) + srcRowBytes * dstBits.height));
  271.         dstBits.space = gxIndexedSpace;
  272.     } else if (dstBits.pixelSize == 16)
  273.         dstBits.space = gxRGB16Space;
  274.     else
  275.         dstBits.space = gxRGB32Space;
  276.     {
  277.         long resourceOffset;
  278.         gxShape pixShape;
  279.         short scans;
  280.         gxLongRectangle bounds;
  281.         
  282.         /*  Decide how many scan lines to copy at once.  If we use smaller chunks than the whole image,
  283.             we never have to load the whole resource into memory, and the graphics system can offload
  284.             pieces of it as they're written.  Otherwise, the whole resource and the whole destination gxShape
  285.             must be in memory at once.  Enough lines to come in just under 32K seems like a reasonable number.
  286.         */
  287.         dstBits.image = nil;
  288.         srcBits = dstBits;
  289.         if (srcRowBytes & 3) {  /* make it a long multiple */
  290.             dstBits.rowBytes = srcRowBytes + 3 & ~3;
  291.             scans = 1;
  292.         } else if (partialReads)
  293.             scans = 1;
  294.         else {
  295.             scans = 32768 / srcRowBytes;
  296.             if (scans == 0)
  297.                 scans = 1;
  298.         }
  299.         if (scans > dstBits.height)
  300.             scans = dstBits.height;
  301.         srcBits.height = scans;
  302.         if (partialReads) {
  303.             resourceOffset = sizeof(PixMap);
  304.             srcBits.image = (char *) NewPtr(srcBits.rowBytes);
  305.             IfDebug(srcBits.image == nil, "\pcouldn't allocate rowBytes");
  306.         } else if ((srcBits.image = (char *) pixmap->baseAddr) == nil)
  307.             srcBits.image = (char *) pixmap + sizeof(PixMap);
  308.         bitsShape = GXNewBitmap(&dstBits, nil);
  309.         pixShape = GXNewBitmap(&dstBits, nil);
  310.         bounds.left = bounds.top = 0;
  311.         bounds.right = srcBits.width;
  312.         bounds.bottom = scans;
  313.         while (bounds.top < dstBits.height) {
  314.             if (partialReads) {
  315.                 ReadPartialResource((Handle) pmHandle, resourceOffset, srcBits.image, srcBits.rowBytes);
  316.                 resourceOffset += srcBits.rowBytes;
  317.             }
  318.             GXSetBitmap(pixShape, &srcBits, nil);
  319.             GXSetBitmapParts(bitsShape, &bounds, pixShape);
  320.             bounds.top += scans;
  321.             bounds.bottom += scans;
  322.             if (bounds.bottom > dstBits.height)
  323.                 bounds.bottom = dstBits.height;
  324.             if (partialReads == false)
  325.                 srcBits.image += scans * srcBits.rowBytes;
  326.         }
  327.         if (partialReads)
  328.             DisposePtr((Ptr) srcBits.image);
  329.         GXDisposeShape(pixShape);
  330.     }
  331.     HSetState((Handle) pmHandle, savedHandleFlags);
  332.     if (dstBits.set)
  333.         GXDisposeColorSet(dstBits.set);
  334.     return bitsShape;
  335. }
  336.  
  337.  
  338. gxShape GetPixMapShape(short resourceID)
  339. {
  340.     PixMapHandle pmHandle;
  341.     
  342.     SetResLoad(false);
  343.     pmHandle = (PixMapHandle) GetResource('pxmp', resourceID);
  344.     SetResLoad(true);
  345.     if (pmHandle) {
  346.         gxShape dest;
  347.         
  348.         dest = PixMapToShape(pmHandle);
  349.         ReleaseResource((Handle)pmHandle);
  350.         return dest;
  351.     } else
  352.         return nil;
  353. }
  354.  
  355. #define kColorSpecSize 8
  356.  
  357. gxShape CICNToMask(CIconHandle iconH)
  358. {
  359.     CIconPtr iconP;
  360.     
  361.     NilParamReturnNil(iconH);
  362.     iconP = *iconH;
  363.     iconP->iconMask.baseAddr = (Ptr) &iconP->iconMaskData;
  364.     return BitMapToShape(&iconP->iconMask);
  365. }
  366.  
  367. gxShape CICNToShape(CIconHandle iconH)
  368. {
  369.     NilParamReturnNil(iconH);
  370.     {   gxShape result = nil;
  371.         CIconPtr iconP = *iconH;
  372.         long height = iconP->iconPMap.bounds.bottom - iconP->iconPMap.bounds.top;
  373.         ColorTable* clut =  (ColorTable*) (((char*)&iconP->iconMaskData) 
  374.                                                 + iconP->iconBMap.rowBytes*height
  375.                                                 + iconP->iconMask.rowBytes*height);
  376.         long clutSize = 8+((clut->ctSize+1)*kColorSpecSize);
  377.     
  378.         PtrToHand((Ptr) clut, (Handle *) &iconP->iconPMap.pmTable, clutSize);
  379.         iconP->iconPMap.baseAddr = (Ptr) (((char *)clut) + clutSize);
  380.         result = PixMapToShape((PixMapHandle) iconH);
  381.         DisposeHandle((Handle) iconP->iconPMap.pmTable);
  382.         return result;
  383.     }
  384. }
  385.     
  386. gxShape GetCICNMask(long resourceID)
  387. {
  388.     gxShape result = nil;
  389.     CIconHandle iconH = (CIconHandle) GetResource('cicn', resourceID);
  390.     
  391.     if (iconH) {
  392.         result = CICNToMask(iconH);
  393.         ReleaseResource((Handle)iconH);
  394.     }
  395.     return result;
  396. }
  397.     
  398. gxShape GetCICNShape(long resourceID)
  399. {
  400.     gxShape result = nil;
  401.     CIconHandle iconH = (CIconHandle) GetResource('cicn', resourceID);
  402.     
  403.     if (iconH) {
  404.         result = CICNToShape(iconH);
  405.         ReleaseResource((Handle)iconH);
  406.     }       
  407.     return result;
  408. }
  409.